//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TridentWordAddIn.Common;
using Microsoft.TridentWordAddIn.ResourceHelper;

namespace Microsoft.TridentWordAddIn.Presentation
{
    /// <summary>
    /// The class OuputUserControl
    /// </summary>
    public partial class OuputUserControl : UserControl
    {
        private bool isBusy;
        private bool isRerunSelected;
        /// <summary>
        /// Occurs when [on save result clicked].
        /// </summary>
        public event EventHandler<SelectedFileEventArgs> OnSaveResultClicked;
        /// <summary>
        /// Occurs when [on result double clicked].
        /// </summary>
        public event EventHandler<SelectedFileEventArgs> OnResultDoubleClicked;
        /// <summary>
        /// Occurs when [on insert result clicked].
        /// </summary>
        public event EventHandler<SelectedFileEventArgs> OnInsertResultClicked;

        /// <summary>
        /// Initializes a new instance of the <see cref="OuputUserControl"/> class.
        /// </summary>
        public OuputUserControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is busy.
        /// </summary>
        /// <value><c>true</c> if this instance is busy; otherwise, <c>false</c>.</value>
        public bool IsBusy
        {
            get
            {
                return this.isBusy;
            }
            set
            {
                if (value != this.isBusy)
                {
                    this.isBusy = value;
                    OnBusyChanged();
                }
            }
        }

        /// <summary>
        /// Gets or sets the message.
        /// </summary>
        /// <value>The message.</value>
        public string Message { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is rerun selected.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is rerun selected; otherwise, <c>false</c>.
        /// </value>
        public bool IsRerunSelected
        {
            get
            {
                return this.isRerunSelected;
            }
            set
            {
                this.isRerunSelected = value;
                if (!this.isRerunSelected)
                {
                    this.IsBusy = false;
                    SetButtonState(true, true);
                }
            }
        }

        /// <summary>
        /// Gets or sets the type of the out put.
        /// </summary>
        /// <value>The type of the out put.</value>
        public OutputType OutPutType { get; set;}

        /// <summary>
        /// Gets the selected result.
        /// </summary>
        /// <value>The selected result.</value>
        public string SelectedResult
        {
            get
            {
                if (this.lvOutput.SelectedIndices.Count > 0)
                {
                    return this.lvOutput.SelectedItems[0].Text;
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// Clears the result.
        /// </summary>
        public void ClearResult()
        {
            this.lvOutput.Items.Clear();
            this.SetButtonState(false, true);
            this.pnlOutput.Controls.Clear();
            this.pnlOutput.Controls.Add(this.lvOutput);
            this.pnlOutput.Controls.Add(this.pnlOutputButton);
        }

        /// <summary>
        /// Updates the result.
        /// </summary>
        public void UpdateResult(List<ShallowJobOutput> results)
        {
            this.lvOutput.Items.Clear();
            if (results.Count == 0)
            {
                this.lvOutput.ShowErrorMessageNoColumn(Message);
                this.SetButtonState(true, false);
                return;
            }

            this.SetButtonState(true, true);
            this.lvOutput.View = View.List;
            ListViewItem newItem = null;
            foreach (ShallowJobOutput output in results)
            {
                newItem = this.lvOutput.Items.Add(output.Name);
                Icon icon = FileHelper.GetFileIcon(output.Extension);
                if (!imlResult.Images.ContainsKey(output.Extension))
                {
                    imlResult.Images.Add(output.Extension, icon);
                }

                newItem.ImageKey = output.Extension;
            }
        }

        /// <summary>
        /// Called when [busy changed].
        /// </summary>
        private void OnBusyChanged()
        {
            if (this.isBusy)
            {
                UserControl jobProcessing = new JobProcessing();
                jobProcessing.Dock = DockStyle.Fill;
                this.pnlOutput.Controls.Clear();
                this.pnlOutput.Controls.Add(jobProcessing);
                this.SetButtonState(false, true);
            }
            else
            {
                this.pnlOutput.Controls.Clear();
                this.pnlOutput.Controls.Add(this.lvOutput);
                this.pnlOutput.Controls.Add(this.pnlOutputButton);
            }
        }

        /// <summary>
        /// Sets the state of the button.
        /// </summary>
        /// <param name="isVisible">if set to <c>true</c> [is visible].</param>
        /// <param name="isEnable">if set to <c>true</c> [is enable].</param>
        private void SetButtonState(bool isVisible, bool isEnable)
        {
            this.pnlOutputButton.Visible = isVisible;
            this.btnSaveOutput.Visible = isVisible;
            this.btnInsertResult.Visible = isVisible;

            this.pnlOutputButton.Enabled = isEnable;
            this.btnSaveOutput.Enabled = isEnable;
            this.btnInsertResult.Enabled = isEnable;
        }

        /// <summary>
        /// Handles the Click event of the btnSaveOutput control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnSaveOutput_Click(object sender, EventArgs e)
        {
            string fileName = this.SelectedResult;
            if (OnSaveResultClicked != null)
            {
                this.OnSaveResultClicked(this, new SelectedFileEventArgs(this.SelectedResult, this.OutPutType));
            }
        }

        /// <summary>
        /// Handles the Click event of the btnInsertResult control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnInsertResult_Click(object sender, EventArgs e)
        {
            string fileName = this.SelectedResult;
            if (OnInsertResultClicked != null)
            {
                this.OnInsertResultClicked(this, new SelectedFileEventArgs(this.SelectedResult, this.OutPutType));
            }
        }

        /// <summary>
        /// Handles the DoubleClick event of the lvOutput control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void lvOutput_DoubleClick(object sender, EventArgs e)
        {
            string fileName = this.SelectedResult;
            if (OnResultDoubleClicked != null)
            {
                this.OnResultDoubleClicked(this, new SelectedFileEventArgs(this.SelectedResult, this.OutPutType));
            }
        }
    }

    /// <summary>
    /// Custom Event Args for Open File dialog Shown
    /// </summary>
    public class SelectedFileEventArgs : EventArgs
    {
        /// <summary>
        /// Gets or sets the intial directory.
        /// </summary>
        /// <value>The intial directory.</value>
        public string FileName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the type of the out put.
        /// </summary>
        /// <value>The type of the out put.</value>
        public OutputType OutPutType
        {
            get;
            set;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SelectedFileEventArgs"/> class.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="outPutType">Type of the out put.</param>
        public SelectedFileEventArgs(string fileName, OutputType outPutType)
        {
            this.FileName = fileName;
            this.OutPutType = outPutType;
        }
    }
}
